#define _CRT_SECURE_NO_WARNINGS

#include "Stack.h"

void StackInit(Stack* stack)
{
	assert(stack);
	stack->arr = NULL;
	stack->top = stack->capacity = 0;
}

void StackDestroy(Stack* stack)
{
	assert(stack);
	free(stack->arr);
	stack->arr = NULL;
	stack->top = stack->capacity = 0;
}

void StackExpandCapacity(Stack* stack)
{
	assert(stack);
	StackDataType* temp = NULL;
	if (stack->capacity == 0)
	{
		temp = realloc(stack->arr, DEFAULT_CAPACITY * sizeof(StackDataType));
		stack->capacity = DEFAULT_CAPACITY;
	}
	else
	{
		temp = realloc(stack->arr, 2 * stack->capacity * sizeof(StackDataType));
		stack->capacity *= 2;
	}
	if (!temp)
	{
		printf("Error:malloc failed.\n");
		assert(1);
	}
	stack->arr = temp;
}

void StackPush(Stack* stack, StackDataType val)
{
	assert(stack);
	if (stack->capacity == stack->top)
	{
		StackExpandCapacity(stack);
	}
	stack->arr[(stack->top)++] = val;
}

void StackPop(Stack* stack)
{
	assert(stack);
	if (stack->top > 0)
	{
		stack->top--;
	}
	else
	{
		printf("Error:the stack is already empty.\n");
	}
}

StackDataType StackTop(const Stack* stack)
{
	assert(stack);
	if (stack->top > 0)
	{
		return stack->arr[(stack->top) - 1];
	}
	else
	{
		printf("The stack is empty.\n");
		return (StackDataType)-1;
	}
}

bool StackIsEmpty(const Stack* stack)
{
	assert(stack);
	if (!stack->top > 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

int StackSize(Stack* stack)
{
	assert(stack);
	return stack->top;
}

void StackPrint(const Stack* stack)
{
	int i = 0;
	for (; i < stack->top; i++)
	{
		printf("%d ", stack->arr[i]);
	}
	printf("(Top)\n");
}